package com.lm.basic;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 * @Auther: Min.Liu
 * @Description:
 * @Date: Created in 8:36 2025/3/13
 */
@Slf4j
public class SocketProcessor implements Runnable {
    private Socket socket;
    private Tomcat tomcat;

    public SocketProcessor(Socket socket, Tomcat tomcat) {
        this.socket = socket;
        this.tomcat = tomcat;
    }

    @Override
    public void run() {
        try {
            processSocket(socket);
        } catch (IOException | ServletException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private void processSocket(Socket socket) throws IOException, ServletException, InstantiationException, IllegalAccessException {
        Request request = createReq(socket);
        Response response = new Response(request);
//        LmServlet servlet = new LmServlet();
//        servlet.service(request,response);
        doServlet(request, response);
        response.Complete();
    }

    private void doServlet(Request request, Response response) throws ServletException, IOException, IllegalAccessException, InstantiationException {
        String[] split = request.getRequestURL().toString().split("/");
        Context context = tomcat.getContextMap().get(split[1]);
        if (context == null) {
            return;
        }
        Class<Servlet> servletClass = context.getUrlPattern("/"+split[2]);
        if (servletClass == null) {
            return;
        }
        Servlet instance = servletClass.newInstance();
        try {
            Method service = HttpServlet.class.getDeclaredMethod("service", HttpServletRequest.class, HttpServletResponse.class);
            //Method service = HttpServlet.class.getMethod("service", HttpServletRequest.class, HttpServletResponse.class);
            service.setAccessible(true);
            service.invoke(instance, request, response);
        } catch (NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
//http://localhost:8080/classes/test
    private Request createReq(Socket socket) throws IOException {
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        inputStream.read(bytes);
        System.out.println(new String(bytes, StandardCharsets.UTF_8));
        System.out.println("==============请求体结束==============");
        int begin = 0, end = 0, pos = 0;
        for (; pos < bytes.length; pos++, end++) {
            if (bytes[pos] == ' ') break;
        }
        StringBuilder method = new StringBuilder();
        for (; begin < end; begin++) {
            method.append((char) bytes[begin]);
        }
        //System.out.println(method.toString());
        begin++;end++;pos++;
        for (; pos < bytes.length; pos++, end++) {
            if (bytes[pos] == ' ') break;
        }
        StringBuilder url = new StringBuilder();
        for (; begin < end; begin++) {
            url.append((char) bytes[begin]);
        }
        //System.out.println(url.toString());
        begin++;end++;pos++;
        for (; pos < bytes.length; pos++, end++) {
            if (bytes[pos] == '\n') break;
        }
        StringBuilder protocol= new StringBuilder();
        for (; begin < end; begin++) {
            protocol.append((char) bytes[begin]);
        }
        //System.out.println(protocol.toString());
        return new Request(method.toString(), url.toString(), protocol.toString(),socket);
    }
}
